import type { CreateConnector, WalletDetailsParams } from '../types/Wallet'
import { createConnector } from '@wagmi/vue'
import type { RoninWaypointWalletConfig } from '../wallets/walletConnectors/roninWaypointWallet/roninWaypointWallet'
import { WaypointProvider } from '@sky-mavis/waypoint'
import { type Chain, createWalletClient, custom, getAddress } from 'viem'
import type { WindowProvider } from '../types'

function createRoninWaypointConnector(roninWaypointWalletConfig: RoninWaypointWalletConfig): CreateConnector {
  // 从自定义配置列表传入walletDetails
  return (walletDetails: WalletDetailsParams) => {
    function getWindow() {
      return typeof window !== 'undefined' ? (window as WindowProvider) : undefined
    }
    const _window = getWindow()
    let provider: WaypointProvider
    return createConnector<WaypointProvider>((config) => ({
      id: 'roninWaypointWalletSDK',
      name: 'Ronin Waypoint',
      type: 'roninWaypoint',
      async connect() {
        provider.on('accountsChanged', this.onAccountsChanged)
        provider.on('chainChanged', this.onChainChanged)
        provider.on('disconnect', this.onDisconnect)
        config.emitter.emit('message', { type: 'connecting' })
        const { token, address } = await provider.connect()

        console.log(token, address)
        const data = {
          accounts: [address],
          chainId: roninWaypointWalletConfig.config.chainId
        }
        config.emitter.emit('connect', data)

        return data
      },
      async getProvider() {
        if (!_window?.roninWaypoint) {
          provider = WaypointProvider.create(roninWaypointWalletConfig.config)
          return provider
        }
        provider = _window.roninWaypoint
        return _window.roninWaypoint
      },
      async disconnect() {
        provider.disconnect()
        provider.removeListener('accountsChanged', this.onAccountsChanged)
        provider.removeListener('chainChanged', this.onChainChanged)
        provider.removeListener('disconnect', this.onDisconnect)
      },
      async getAccounts() {
        return await provider.request({ method: 'eth_accounts' })
      },
      async getChainId() {
        const chainId = await provider.request({ method: 'eth_chainId' })
        return Number(chainId)
      },
      async isAuthorized() {
        return Boolean(provider['address'])
      },
      async getClient({ chainId } = {}) {
        const chain = config.chains.find((x) => x.id === chainId)
        return createWalletClient({
          transport: custom(provider),
          chain: chain as Chain
        })
      },
      async switchChain({ addEthereumChainParameter, chainId }) {
        // todo 这边要判断一下ronin支持切换的链子
        console.log(chainId, '连接器里面', addEthereumChainParameter)
        return Promise.reject('RoninWaypoint当前不支持切链')
      },
      async onAccountsChanged(accounts) {
        const chainId = await provider.request({ method: 'eth_chainId' })
        if (accounts.length === 0) config.emitter.emit('disconnect')
        else
          config.emitter.emit('change', {
            accounts: accounts.map((account) => getAddress(account)),
            chainId: chainId as number
          })
      },
      async onChainChanged(chain: string) {
        const chainId = Number(chain)
        config.emitter.emit('change', { chainId })
      },
      async onDisconnect() {
        provider.disconnect()
        config.emitter.emit('disconnect')
      },
      ...walletDetails
    }))
  }
}

export function getRoninWaypointConnector(roninWaypointWalletConfig: RoninWaypointWalletConfig): CreateConnector {
  return createRoninWaypointConnector(roninWaypointWalletConfig)
}
